import os
from datetime import datetime
from flask import Blueprint, request, jsonify, current_app
from flask_jwt_extended import jwt_required, get_jwt_identity
from werkzeug.utils import secure_filename
from sqlalchemy import or_
from app import db
from app.models.banner import Banner
from app.models.admin import Admin
from app.utils.response import success_response, error_response
from app.utils.banner_validator import BannerValidator
from flasgger import swag_from

banner_bp = Blueprint('admin_banner', __name__)

@banner_bp.route('/banners', methods=['GET'])
@jwt_required()
@swag_from({
    'tags': ['Banner管理'],
    'summary': '获取Banner列表',
    'description': '''管理员获取Banner列表，支持分页和筛选。返回完整的Banner信息包括状态、点击统计等数据。
    
    跳转类型说明：
    • external: 外部链接跳转（如网站链接）
    • internal: 内部页面跳转（如应用内的页面路径）
    • venue: 场馆详情页跳转（跳转到指定场馆的详情页面）
    • miniprogram: 小程序跳转（跳转到指定的小程序页面，需要AppID）
    • none: 纯展示（仅展示图片，无任何跳转操作）
    ''',
    'parameters': [
        {
            'name': 'page',
            'in': 'query',
            'type': 'integer',
            'default': 1,
            'description': '页码，从1开始'
        },
        {
            'name': 'per_page',
            'in': 'query',
            'type': 'integer',
            'default': 10,
            'description': '每页数量，最大100'
        },
        {
            'name': 'status',
            'in': 'query',
            'type': 'integer',
            'enum': [0, 1],
            'description': 'Banner状态筛选：0=禁用（不在前端显示），1=启用（正常显示）'
        },
        {
            'name': 'keyword',
            'in': 'query',
            'type': 'string',
            'description': '关键词搜索（根据Banner标题模糊匹配）'
        }
    ],
    'responses': {
        200: {
            'description': '获取成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200, 'description': '状态码'},
                    'message': {'type': 'string', 'example': '获取成功', 'description': '响应消息'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'banners': {
                                'type': 'array',
                                'description': 'Banner列表',
                                'items': {
                                    'type': 'object',
                                    'properties': {
                                        'id': {'type': 'integer', 'description': 'Banner ID'},
                                        'title': {'type': 'string', 'description': 'Banner标题'},
                                        'description': {'type': 'string', 'description': 'Banner描述'},
                                        'image_url': {'type': 'string', 'description': '图片URL地址'},
                                        'link_url': {'type': 'string', 'description': '跳转链接（external类型时使用）'},
                                        'link_type': {'type': 'string', 'enum': ['external', 'internal', 'venue', 'miniprogram', 'none'], 'description': '''跳转类型：
                                        • external=外部链接（如https://example.com）
                                        • internal=内部页面（如/venues、/activities等应用内页面）
                                        • venue=场馆详情（跳转到指定场馆的详情页面）
                                        • miniprogram=小程序跳转（跳转到其他小程序的指定页面）
                                        • none=纯展示（无跳转操作，仅作为图片展示）'''},
                                        'link_target': {'type': 'string', 'description': '''跳转目标：
                                        • external类型：不使用此字段，跳转地址在link_url中
                                        • internal类型：页面路径（如"/venues"、"/activities"）
                                        • venue类型：场馆ID（如"123"）
                                        • miniprogram类型：小程序页面路径（如"pages/index/index"）
                                        • none类型：不使用此字段'''},
                                        'link_appid': {'type': 'string', 'description': '小程序AppID（仅miniprogram类型时使用，如"wx1234567890abcdef"）'},
                                        'sort_order': {'type': 'integer', 'description': '排序序号，数字越小越靠前'},
                                        'status': {'type': 'integer', 'enum': [0, 1], 'description': 'Banner状态：0=禁用，1=启用'},
                                        'start_time': {'type': 'string', 'format': 'date-time', 'description': '开始展示时间（可选）'},
                                        'end_time': {'type': 'string', 'format': 'date-time', 'description': '结束展示时间（可选）'},
                                        'click_count': {'type': 'integer', 'description': '点击统计次数'},
                                        'created_at': {'type': 'string', 'format': 'date-time', 'description': '创建时间'},
                                        'updated_at': {'type': 'string', 'format': 'date-time', 'description': '更新时间'},
                                        'creator_name': {'type': 'string', 'description': '创建人姓名'}
                                    }
                                }
                            },
                            'total': {'type': 'integer', 'description': '总记录数'},
                            'page': {'type': 'integer', 'description': '当前页码'},
                            'pages': {'type': 'integer', 'description': '总页数'},
                            'per_page': {'type': 'integer', 'description': '每页数量'}
                        }
                    }
                }
            }
        },
        400: {
            'description': '请求参数错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 400},
                    'message': {'type': 'string', 'example': '请求参数错误'}
                }
            }
        },
        401: {
            'description': '未授权访问',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 401},
                    'message': {'type': 'string', 'example': '未授权访问'}
                }
            }
        },
        500: {
            'description': '服务器内部错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 500},
                    'message': {'type': 'string', 'example': '获取失败'}
                }
            }
        }
    }
})
def get_banners():
    """获取Banner列表"""
    try:
        # 获取查询参数
        page = request.args.get('page', 1, type=int)
        per_page = min(request.args.get('per_page', 10, type=int), 100)
        status = request.args.get('status', type=int)
        keyword = request.args.get('keyword', '').strip()
        
        # 构建查询
        query = Banner.query
        
        # 状态筛选
        if status is not None:
            query = query.filter(Banner.status == status)
        
        # 关键词搜索
        if keyword:
            query = query.filter(Banner.title.contains(keyword))
        
        # 排序
        query = query.order_by(Banner.sort_order.asc(), Banner.created_at.desc())
        
        # 分页
        pagination = query.paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        banners = []
        for banner in pagination.items:
            banner_data = banner.to_dict(include_stats=True)
            banners.append(banner_data)
        
        return success_response({
            'banners': banners,
            'total': pagination.total,
            'page': page,
            'pages': pagination.pages,
            'per_page': per_page
        }, '获取成功')
        
    except Exception as e:
        current_app.logger.error(f"获取Banner列表失败: {str(e)}")
        return error_response('获取失败', 500)

@banner_bp.route('/banners', methods=['POST'])
@jwt_required()
@swag_from({
    'tags': ['Banner管理'],
    'summary': '创建Banner',
    'description': '''管理员创建新的Banner轮播图。创建成功后返回完整的Banner信息。
    
    跳转类型配置说明：
    1. external（外部链接）：需设置link_url为完整URL，link_target和link_appid留空
    2. internal（内部页面）：需设置link_target为页面路径（如"/venues"），link_url和link_appid留空
    3. venue（场馆详情）：需设置link_target为场馆ID，link_url和link_appid留空
    4. miniprogram（小程序跳转）：需设置link_target为小程序页面路径，link_appid为目标小程序AppID，link_url留空
    5. none（纯展示）：所有跳转相关字段都留空
    ''',
    'parameters': [
        {
            'name': 'body',
            'in': 'body',
            'required': True,
            'schema': {
                'type': 'object',
                'required': ['title', 'image_url'],
                'properties': {
                    'title': {'type': 'string', 'maxLength': 100, 'description': 'Banner标题（必填，最大100字符）'},
                    'description': {'type': 'string', 'maxLength': 200, 'description': 'Banner描述（可选，最大200字符）'},
                    'image_url': {'type': 'string', 'description': '图片URL地址（必填，建议尺寸750x300）'},
                    'link_url': {'type': 'string', 'description': '跳转链接（external类型时必填）'},
                    'link_type': {'type': 'string', 'enum': ['external', 'internal', 'venue', 'miniprogram', 'none'], 'default': 'external', 'description': '''跳转类型：
                    • external=外部链接（跳转到外部网站）
                    • internal=内部页面（跳转到应用内页面）
                    • venue=场馆详情（跳转到指定场馆详情页）
                    • miniprogram=小程序跳转（跳转到其他小程序）
                    • none=纯展示（无跳转功能）'''},
                    'link_target': {'type': 'string', 'description': '''跳转目标（根据link_type类型填写）：
                    • internal类型：页面路径，如"/venues"、"/activities"
                    • venue类型：场馆ID，如"123"
                    • miniprogram类型：小程序页面路径，如"pages/index/index"
                    • external和none类型：不需要填写'''},
                    'link_appid': {'type': 'string', 'description': '小程序AppID（仅miniprogram类型时必填，如"wx1234567890abcdef"）'},
                    'sort_order': {'type': 'integer', 'minimum': 0, 'default': 0, 'description': '排序序号（数字越小越靠前，默认0）'},
                    'status': {'type': 'integer', 'enum': [0, 1], 'default': 1, 'description': 'Banner状态：0=禁用，1=启用（默认启用）'},
                    'start_time': {'type': 'string', 'format': 'date-time', 'description': '开始展示时间（可选，ISO格式如2025-06-12T10:00:00）'},
                    'end_time': {'type': 'string', 'format': 'date-time', 'description': '结束展示时间（可选，必须晚于开始时间）'}
                },
                'examples': {
                    'external_link': {
                        'summary': '外部链接Banner',
                        'value': {
                            'title': '官方网站',
                            'description': '访问我们的官方网站了解更多信息',
                            'image_url': '/uploads/banner/banner_website.jpg',
                            'link_type': 'external',
                            'link_url': 'https://www.example.com',
                            'sort_order': 1,
                            'status': 1
                        }
                    },
                    'internal_page': {
                        'summary': '内部页面Banner',
                        'value': {
                            'title': '场馆列表',
                            'description': '查看所有可预订的场馆',
                            'image_url': '/uploads/banner/banner_venues.jpg',
                            'link_type': 'internal',
                            'link_target': '/venues',
                            'sort_order': 2,
                            'status': 1
                        }
                    },
                    'venue_detail': {
                        'summary': '场馆详情Banner',
                        'value': {
                            'title': '推荐场馆',
                            'description': '新开业的篮球场，设施一流',
                            'image_url': '/uploads/banner/banner_venue.jpg',
                            'link_type': 'venue',
                            'link_target': '123',
                            'sort_order': 3,
                            'status': 1
                        }
                    },
                    'miniprogram': {
                        'summary': '小程序跳转Banner',
                        'value': {
                            'title': '积分商城',
                            'description': '前往积分商城兑换好礼',
                            'image_url': '/uploads/banner/banner_points.jpg',
                            'link_type': 'miniprogram',
                            'link_target': 'pages/mall/index',
                            'link_appid': 'wx1234567890abcdef',
                            'sort_order': 4,
                            'status': 1
                        }
                    },
                    'display_only': {
                        'summary': '纯展示Banner',
                        'value': {
                            'title': '品牌形象',
                            'description': '展示企业文化和理念',
                            'image_url': '/uploads/banner/banner_brand.jpg',
                            'link_type': 'none',
                            'sort_order': 5,
                            'status': 1
                        }
                    }
                }
            }
        }
    ],
    'responses': {
        200: {
            'description': '创建成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200, 'description': '状态码'},
                    'message': {'type': 'string', 'example': '创建成功', 'description': '响应消息'},
                    'data': {
                        'type': 'object',
                        'description': '创建的Banner完整信息',
                        'properties': {
                            'id': {'type': 'integer', 'description': '新创建的Banner ID'},
                            'title': {'type': 'string', 'description': 'Banner标题'},
                            'description': {'type': 'string', 'description': 'Banner描述'},
                            'image_url': {'type': 'string', 'description': '图片URL地址'},
                            'link_url': {'type': 'string', 'description': '跳转链接'},
                            'link_type': {'type': 'string', 'description': '跳转类型'},
                            'link_target': {'type': 'string', 'description': '跳转目标'},
                            'sort_order': {'type': 'integer', 'description': '排序序号'},
                            'status': {'type': 'integer', 'description': 'Banner状态：0=禁用，1=启用'},
                            'start_time': {'type': 'string', 'format': 'date-time', 'description': '开始展示时间'},
                            'end_time': {'type': 'string', 'format': 'date-time', 'description': '结束展示时间'},
                            'click_count': {'type': 'integer', 'example': 0, 'description': '点击统计次数（新创建为0）'},
                            'created_at': {'type': 'string', 'format': 'date-time', 'description': '创建时间'},
                            'updated_at': {'type': 'string', 'format': 'date-time', 'description': '更新时间'},
                            'creator_name': {'type': 'string', 'description': '创建人姓名'}
                        }
                    }
                }
            }
        },
        400: {
            'description': '请求参数错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 400},
                    'message': {'type': 'string', 'example': '标题不能为空'}
                }
            }
        },
        401: {
            'description': '未授权访问',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 401},
                    'message': {'type': 'string', 'example': '未授权访问'}
                }
            }
        },
        500: {
            'description': '服务器内部错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 500},
                    'message': {'type': 'string', 'example': '创建失败'}
                }
            }
        }
    }
})
def create_banner():
    """创建Banner"""
    try:
        data = request.get_json()
        
        # 使用验证器验证数据
        try:
            BannerValidator.validate_banner_data(data)
        except ValueError as e:
            return error_response(str(e))
        
        # 获取当前用户ID
        current_user_id = get_jwt_identity()
        
        # 处理时间字段
        start_time = None
        end_time = None
        
        if data.get('start_time'):
            try:
                start_time = datetime.fromisoformat(data['start_time'].replace('Z', '+00:00'))
            except ValueError:
                return error_response('开始时间格式错误，请使用ISO格式')
        
        if data.get('end_time'):
            try:
                end_time = datetime.fromisoformat(data['end_time'].replace('Z', '+00:00'))
            except ValueError:
                return error_response('结束时间格式错误，请使用ISO格式')
        
        # 验证时间逻辑
        if start_time and end_time and start_time >= end_time:
            return error_response('开始时间必须早于结束时间')
        
        # 清理数据，移除不需要的字段
        link_type = data.get('link_type', 'external')
        cleaned_data = BannerValidator.clean_banner_data(data, link_type)
        
        # 创建Banner
        banner = Banner(
            title=cleaned_data['title'].strip(),
            description=cleaned_data.get('description', '').strip(),
            image_url=cleaned_data['image_url'].strip(),
            link_url=cleaned_data.get('link_url', ''),
            link_type=link_type,
            link_target=cleaned_data.get('link_target', ''),
            link_appid=cleaned_data.get('link_appid', ''),
            sort_order=cleaned_data.get('sort_order', 0),
            status=cleaned_data.get('status', 1),
            start_time=start_time,
            end_time=end_time,
            created_by=current_user_id
        )
        
        db.session.add(banner)
        db.session.commit()
        
        return success_response(banner.to_dict(), '创建成功')
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"创建Banner失败: {str(e)}")
        return error_response('创建失败', 500)

@banner_bp.route('/banners/<int:banner_id>', methods=['PUT'])
@jwt_required()
@swag_from({
    'tags': ['Banner管理'],
    'summary': '更新Banner',
    'description': '''管理员更新Banner信息。支持部分字段更新，未传递的字段保持原值不变。
    
    跳转类型配置说明（与创建接口相同）：
    1. external：link_url为完整URL，其他跳转字段留空
    2. internal：link_target为页面路径，其他跳转字段留空
    3. venue：link_target为场馆ID，其他跳转字段留空
    4. miniprogram：link_target为页面路径，link_appid为小程序AppID，link_url留空
    5. none：所有跳转字段都留空
    ''',
    'parameters': [
        {
            'name': 'banner_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': 'Banner ID'
        },
        {
            'name': 'body',
            'in': 'body',
            'required': True,
            'schema': {
                'type': 'object',
                'properties': {
                    'title': {'type': 'string', 'description': '标题'},
                    'description': {'type': 'string', 'description': '描述'},
                    'image_url': {'type': 'string', 'description': '图片URL'},
                    'link_url': {'type': 'string', 'description': '跳转链接'},
                    'link_type': {'type': 'string', 'enum': ['external', 'internal', 'venue', 'miniprogram', 'none'], 'description': '跳转类型：external=外部链接，internal=内部页面，venue=场馆详情，miniprogram=小程序跳转，none=纯展示'},
                    'link_target': {'type': 'string', 'description': '跳转目标：internal类型为页面路径，venue类型为场馆ID，miniprogram类型为小程序页面路径'},
                    'link_appid': {'type': 'string', 'description': '小程序AppID（miniprogram类型时使用）'},
                    'sort_order': {'type': 'integer', 'description': '排序序号'},
                    'status': {'type': 'integer', 'enum': [0, 1], 'description': '状态'},
                    'start_time': {'type': 'string', 'format': 'date-time', 'description': '开始时间'},
                    'end_time': {'type': 'string', 'format': 'date-time', 'description': '结束时间'}
                }
            }
        }
    ],
    'responses': {
        200: {
            'description': '更新成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '更新成功'},
                    'data': {
                        'type': 'object',
                        'description': '更新后的数据'
                    }
                }
            }
        }
    }
})
def update_banner(banner_id):
    """更新Banner"""
    try:
        banner = Banner.query.get(banner_id)
        if not banner:
            return error_response('Banner不存在', 404)
        
        data = request.get_json()
        
        # 使用验证器验证更新数据
        try:
            BannerValidator.validate_banner_data(data, is_update=True)
        except ValueError as e:
            return error_response(str(e))
        
        # 获取链接类型（可能是新的或现有的）
        link_type = data.get('link_type', banner.link_type)
        
        # 清理数据
        cleaned_data = BannerValidator.clean_banner_data(data, link_type)
        
        # 更新字段
        if 'title' in cleaned_data:
            banner.title = cleaned_data['title'].strip()
        
        if 'description' in cleaned_data:
            banner.description = cleaned_data['description'].strip()
        
        if 'image_url' in cleaned_data:
            banner.image_url = cleaned_data['image_url'].strip()
        
        if 'link_url' in cleaned_data:
            banner.link_url = cleaned_data['link_url']
        
        if 'link_type' in cleaned_data:
            banner.link_type = cleaned_data['link_type']
        
        if 'link_target' in cleaned_data:
            banner.link_target = cleaned_data['link_target']
        
        if 'link_appid' in cleaned_data:
            banner.link_appid = cleaned_data['link_appid']
        
        if 'sort_order' in cleaned_data:
            banner.sort_order = cleaned_data['sort_order']
        
        if 'status' in cleaned_data:
            banner.status = cleaned_data['status']
        
        # 处理时间字段
        if 'start_time' in data:
            if data['start_time']:
                try:
                    banner.start_time = datetime.fromisoformat(data['start_time'].replace('Z', '+00:00'))
                except ValueError:
                    return error_response('开始时间格式错误，请使用ISO格式')
            else:
                banner.start_time = None
        
        if 'end_time' in data:
            if data['end_time']:
                try:
                    banner.end_time = datetime.fromisoformat(data['end_time'].replace('Z', '+00:00'))
                except ValueError:
                    return error_response('结束时间格式错误，请使用ISO格式')
            else:
                banner.end_time = None
        
        # 验证时间逻辑
        if banner.start_time and banner.end_time and banner.start_time >= banner.end_time:
            return error_response('开始时间必须早于结束时间')
        
        db.session.commit()
        
        return success_response(banner.to_dict(), '更新成功')
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"更新Banner失败: {str(e)}")
        return error_response('更新失败', 500)

@banner_bp.route('/banners/<int:banner_id>', methods=['DELETE'])
@jwt_required()
@swag_from({
    'tags': ['Banner管理'],
    'summary': '删除Banner',
    'description': '管理员删除Banner',
    'parameters': [
        {
            'name': 'banner_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': 'Banner ID'
        }
    ],
    'responses': {
        200: {
            'description': '删除成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '删除成功'}
                }
            }
        }
    }
})
def delete_banner(banner_id):
    """删除Banner"""
    try:
        banner = Banner.query.get(banner_id)
        if not banner:
            return error_response('Banner不存在', 404)
        
        db.session.delete(banner)
        db.session.commit()
        
        return success_response(None, '删除成功')
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"删除Banner失败: {str(e)}")
        return error_response('删除失败', 500)

@banner_bp.route('/banners/<int:banner_id>', methods=['GET'])
@jwt_required()
@swag_from({
    'tags': ['Banner管理'],
    'summary': '获取Banner详情',
    'description': '管理员获取单个Banner的详细信息，包括完整的跳转配置、统计数据等。',
    'parameters': [
        {
            'name': 'banner_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': 'Banner ID'
        }
    ],
    'responses': {
        200: {
            'description': '获取成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200, 'description': '状态码'},
                    'message': {'type': 'string', 'example': '获取成功', 'description': '响应消息'},
                    'data': {
                        'type': 'object',
                        'description': 'Banner详细信息',
                        'properties': {
                            'id': {'type': 'integer', 'description': 'Banner ID'},
                            'title': {'type': 'string', 'description': 'Banner标题'},
                            'description': {'type': 'string', 'description': 'Banner描述'},
                            'image_url': {'type': 'string', 'description': '图片URL地址'},
                            'link_url': {'type': 'string', 'description': '跳转链接（external类型时使用）'},
                            'link_type': {'type': 'string', 'enum': ['external', 'internal', 'venue', 'miniprogram', 'none'], 'description': '跳转类型'},
                            'link_target': {'type': 'string', 'description': '跳转目标'},
                            'link_appid': {'type': 'string', 'description': '小程序AppID（miniprogram类型时使用）'},
                            'sort_order': {'type': 'integer', 'description': '排序序号'},
                            'status': {'type': 'integer', 'enum': [0, 1], 'description': 'Banner状态：0=禁用，1=启用'},
                            'start_time': {'type': 'string', 'format': 'date-time', 'description': '开始展示时间'},
                            'end_time': {'type': 'string', 'format': 'date-time', 'description': '结束展示时间'},
                            'click_count': {'type': 'integer', 'description': '点击统计次数'},
                            'created_at': {'type': 'string', 'format': 'date-time', 'description': '创建时间'},
                            'updated_at': {'type': 'string', 'format': 'date-time', 'description': '更新时间'},
                            'creator_name': {'type': 'string', 'description': '创建人姓名'}
                        }
                    }
                }
            }
        },
        404: {
            'description': 'Banner不存在',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 404},
                    'message': {'type': 'string', 'example': 'Banner不存在'}
                }
            }
        },
        401: {
            'description': '未授权访问',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 401},
                    'message': {'type': 'string', 'example': '未授权访问'}
                }
            }
        },
        500: {
            'description': '服务器内部错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 500},
                    'message': {'type': 'string', 'example': '获取失败'}
                }
            }
        }
    }
})
def get_banner_detail(banner_id):
    """获取Banner详情"""
    try:
        banner = Banner.query.get(banner_id)
        if not banner:
            return error_response('Banner不存在', 404)
        
        return success_response(banner.to_dict(include_stats=True), '获取成功')
        
    except Exception as e:
        current_app.logger.error(f"获取Banner详情失败: {str(e)}")
        return error_response('获取失败', 500)

@banner_bp.route('/banners/upload', methods=['POST'])
@jwt_required()
@swag_from({
    'tags': ['Banner管理'],
    'summary': '上传Banner图片',
    'description': '''管理员上传Banner图片文件。支持常见图片格式，上传成功后返回完整的HTTPS图片URL。
    
    支持的图片格式：png、jpg、jpeg、gif、webp
    建议图片尺寸：750x300像素（宽高比2.5:1）
    文件大小限制：请控制在4MB以内
    ''',
    'consumes': ['multipart/form-data'],
    'parameters': [
        {
            'name': 'file',
            'in': 'formData',
            'type': 'file',
            'required': True,
            'description': '图片文件（支持png、jpg、jpeg、gif、webp格式）'
        }
    ],
    'responses': {
        200: {
            'description': '上传成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200, 'description': '状态码'},
                    'message': {'type': 'string', 'example': '上传成功', 'description': '响应消息'},
                    'data': {
                        'type': 'object',
                        'description': '上传结果',
                        'properties': {
                            'url': {'type': 'string', 'example': '/uploads/banner/banner_1640995200000_image.jpg', 'description': '图片的相对访问URL'},
                            'filename': {'type': 'string', 'example': 'banner_1640995200000_image.jpg', 'description': '服务器端保存的文件名'}
                        }
                    }
                }
            }
        },
        400: {
            'description': '请求参数错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 400},
                    'message': {'type': 'string', 'example': '请选择文件或不支持的文件格式'}
                }
            }
        },
        401: {
            'description': '未授权访问',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 401},
                    'message': {'type': 'string', 'example': '未授权访问'}
                }
            }
        },
        500: {
            'description': '服务器内部错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 500},
                    'message': {'type': 'string', 'example': '上传失败'}
                }
            }
        }
    }
})
def upload_banner_image():
    """上传Banner图片"""
    try:
        if 'file' not in request.files:
            return error_response('请选择文件')
        
        file = request.files['file']
        
        # 使用验证器验证上传文件
        try:
            BannerValidator.validate_upload_file(file)
        except ValueError as e:
            return error_response(str(e))
        
        # 生成安全的文件名
        filename = secure_filename(file.filename)
        timestamp = int(datetime.now().timestamp() * 1000)
        filename = f"banner_{timestamp}_{filename}"
        
        # 确保banner专用上传目录存在
        banner_upload_folder = '/home/www/venue_booking_system/uploads/banner'
        if not os.path.exists(banner_upload_folder):
            os.makedirs(banner_upload_folder, mode=0o755)
        
        # 保存文件到banner目录
        file_path = os.path.join(banner_upload_folder, filename)
        file.save(file_path)
        
        # 设置文件权限
        os.chmod(file_path, 0o644)
        
        # 返回文件URL - 只返回相对路径，不包含域名
        file_url = f"/uploads/banner/{filename}"
        
        return success_response({
            'url': file_url,
            'filename': filename
        }, '上传成功')
        
    except Exception as e:
        current_app.logger.error(f"上传Banner图片失败: {str(e)}")
        return error_response('上传失败', 500)

@banner_bp.route('/banners/<int:banner_id>/status', methods=['PUT'])
@jwt_required()
@swag_from({
    'tags': ['Banner管理'],
    'summary': '切换Banner状态',
    'description': '管理员切换Banner启用/禁用状态。禁用后Banner将不在用户端显示，启用后立即生效。',
    'parameters': [
        {
            'name': 'banner_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '要切换状态的Banner ID'
        },
        {
            'name': 'body',
            'in': 'body',
            'required': True,
            'schema': {
                'type': 'object',
                'required': ['status'],
                'properties': {
                    'status': {'type': 'integer', 'enum': [0, 1], 'description': 'Banner状态：0=禁用（不在前端显示），1=启用（正常显示）'}
                },
                'example': {
                    'status': 1
                }
            }
        }
    ],
    'responses': {
        200: {
            'description': '状态更新成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200, 'description': '状态码'},
                    'message': {'type': 'string', 'example': 'Banner已启用', 'description': '响应消息（显示具体的状态变更结果）'},
                    'data': {
                        'type': 'object',
                        'description': '更新后的Banner完整信息',
                        'properties': {
                            'id': {'type': 'integer', 'description': 'Banner ID'},
                            'title': {'type': 'string', 'description': 'Banner标题'},
                            'description': {'type': 'string', 'description': 'Banner描述'},
                            'image_url': {'type': 'string', 'description': '图片URL地址'},
                            'link_url': {'type': 'string', 'description': '跳转链接'},
                            'link_type': {'type': 'string', 'description': '跳转类型'},
                            'link_target': {'type': 'string', 'description': '跳转目标'},
                            'sort_order': {'type': 'integer', 'description': '排序序号'},
                            'status': {'type': 'integer', 'enum': [0, 1], 'description': '更新后的Banner状态：0=禁用，1=启用'},
                            'start_time': {'type': 'string', 'format': 'date-time', 'description': '开始展示时间'},
                            'end_time': {'type': 'string', 'format': 'date-time', 'description': '结束展示时间'},
                            'click_count': {'type': 'integer', 'description': '点击统计次数'},
                            'created_at': {'type': 'string', 'format': 'date-time', 'description': '创建时间'},
                            'updated_at': {'type': 'string', 'format': 'date-time', 'description': '更新时间'},
                            'creator_name': {'type': 'string', 'description': '创建人姓名'}
                        }
                    }
                }
            }
        },
        400: {
            'description': '请求参数错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 400},
                    'message': {'type': 'string', 'example': '无效的状态值'}
                }
            }
        },
        401: {
            'description': '未授权访问',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 401},
                    'message': {'type': 'string', 'example': '未授权访问'}
                }
            }
        },
        404: {
            'description': 'Banner不存在',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 404},
                    'message': {'type': 'string', 'example': 'Banner不存在'}
                }
            }
        },
        500: {
            'description': '服务器内部错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 500},
                    'message': {'type': 'string', 'example': '状态更新失败'}
                }
            }
        }
    }
})
def toggle_banner_status(banner_id):
    """切换Banner状态"""
    try:
        banner = Banner.query.get(banner_id)
        if not banner:
            return error_response('Banner不存在', 404)
        
        data = request.get_json()
        status = data.get('status')
        
        if status not in [0, 1]:
            return error_response('无效的状态值')
        
        banner.status = status
        db.session.commit()
        
        status_text = '启用' if status == 1 else '禁用'
        return success_response(banner.to_dict(), f'Banner已{status_text}')
        
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(f"切换Banner状态失败: {str(e)}")
        return error_response('状态更新失败', 500) 